﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using Community.CsharpSqlite;
using Microsoft.Maps.MapControl;
using iPhoneTracker4Win.Models;
using QuadTreeLib;
using System.Drawing;

namespace iPhoneTracker4Win
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            //map.TargetViewChanged += new EventHandler<MapEventArgs>(map_TargetViewChanged);
            map.ViewChangeEnd += new EventHandler<MapEventArgs>(map_ViewChangeEnd);
        }

        void map_ViewChangeEnd(object sender, MapEventArgs e)
        {
            var locationRect = map.TargetBoundingRectangle;
            var rect = new RectangleF(locationRect.West, locationRect.South, locationRect.Width, locationRect.Height);
            var timeLocations = spatial.Query(rect);
            foreach (var item in map.Children)
            {
                item.Visibility = System.Windows.Visibility.Collapsed;
            }
            foreach (var item in timeLocations)
            {
                Pushpin pin = pushpins[item];
                pin.Visibility = System.Windows.Visibility.Visible;
            }
        }

        ScaleTransform transform = new ScaleTransform { ScaleX = 0.5, ScaleY = 0.5, CenterX = 17, CenterY = 35 };
        SolidColorBrush blueBrush = new SolidColorBrush(Colors.Blue);
        SolidColorBrush redBrush = new SolidColorBrush(Colors.Red);

        void map_TargetViewChanged(object sender, MapEventArgs e)
        {
        }

        List<TimeLocation> records = new List<TimeLocation>();
        QuadTree<TimeLocation> spatial = new QuadTree<TimeLocation>(new RectangleF(-180.0, -90.0, 360.0, 180.0));
        Dictionary<TimeLocation, Pushpin> pushpins = new Dictionary<TimeLocation, Pushpin>();

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dia = new OpenFileDialog();
            if (dia.ShowDialog().Value)
            {
                IntPtr sqlite_handle = new IntPtr(1);
                Sqlite3.sqlite3 sqlite_handle2 = new Sqlite3.sqlite3();
                string db_file = dia.File.FullName;
                int flags = Sqlite3.SQLITE_OPEN_NOMUTEX | Sqlite3.SQLITE_OPEN_READWRITE | Sqlite3.SQLITE_OPEN_CREATE;
                int err = Sqlite3.sqlite3_open_v2(db_file, ref sqlite_handle2, flags, null);
                string pzErrMsg = "";
                Sqlite3.sqlite3_exec(sqlite_handle2, "SELECT * FROM CellLocation", CellLocationCallback, null, ref pzErrMsg);
                Sqlite3.sqlite3_exec(sqlite_handle2, "SELECT * FROM WifiLocation", WifiLocationCallback, null, ref pzErrMsg);
            }
        }

        private int CellLocationCallback(object pCallbackArg, Int64 argc, object azVals, object azCols)
        {
            var type = TimeLocationType.CellLocation;
            string[] vals = (string[])azVals;
            string[] cols = (string[])azCols;

            double timestamp = double.Parse(vals[4]);
            double latitude = double.Parse(vals[5]);
            double longitude = double.Parse(vals[6]);
            AddTimeLocationRecord(timestamp, latitude, longitude, type);
            return 0;
        }

        private int WifiLocationCallback(object pCallbackArg, Int64 argc, object azVals, object azCols)
        {
            var type = TimeLocationType.WifiLocation;
            string[] vals = (string[])azVals;
            string[] cols = (string[])azCols;

            double timestamp = double.Parse(vals[1]);
            double latitude = double.Parse(vals[2]);
            double longitude = double.Parse(vals[3]);
            AddTimeLocationRecord(timestamp, latitude, longitude, type);
            return 0;
        }

        int counter = 0;

        private void AddTimeLocationRecord(double timestamp, double latitude, double longitude, TimeLocationType type)
        {
            if (latitude == 0.0 || latitude == 0.0)
            {
                return;
            }
            if (++counter % 50 != 0)
            {
                return;
            }
            var timeLocation = new TimeLocation(DateTime.Now, new Location(latitude, longitude), type);
            spatial.Insert(timeLocation);
            records.Add(timeLocation);

            Pushpin pin = new Pushpin();
            pin.Location = timeLocation.Location;
            pin.RenderTransform = transform;
            if (timeLocation.Type == TimeLocationType.WifiLocation)
            {
                pin.Background = blueBrush;
            }
            else
            {
                pin.Background = redBrush;
            }
            pushpins[timeLocation] = pin;
            map.Children.Add(pin);
        }
    }
}
